package com.px.lovepath.utils.session;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.HttpEntityWrapper;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.ByteArrayBuffer;
import org.json.JSONObject;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import com.px.lovepath.utils.network.HttpHeaders;

public class WebService {
	protected final static String TAG = WebService.class.getName();
	protected final WebSession mWebSession;
	
	// ### 内嵌类 ###
	private class GzipEntityWrapper extends HttpEntityWrapper {
		private final GZIPInputStream mGzipStreamWrapper;
		
		public GzipEntityWrapper(HttpEntity gzipEntity) throws IllegalStateException, IOException {
			super(gzipEntity);
			
			mGzipStreamWrapper = new GZIPInputStream(gzipEntity.getContent());
		}
		
		@Override
		public Header getContentEncoding() {
			return null;
		}
		@Override
		public InputStream getContent() {
			return mGzipStreamWrapper;
		}
	}
	
	// ### 构造函数 ###
	public WebService(WebSession webSession) {
		assert webSession != null;
		
		mWebSession = webSession;
	}

	// ### 方法 ###
	public Bitmap getBitmapContent(String uri) throws Exception {
		HttpGet httpRequest = new HttpGet(uri);
		HttpResponse httpResponse = execute(httpRequest);
		HttpEntity entity = httpResponse.getEntity();

		InputStream stream = entity.getContent();
		Bitmap bitmapContent = BitmapFactory.decodeStream(stream);
		stream.close();
		entity.consumeContent();
		return bitmapContent;
	}
	public JSONObject getJsonContent(String uri) throws Exception {
		String stringContent = getStringContent(uri);
		JSONObject jsonContent = new JSONObject(stringContent);
		return jsonContent;
	}	
	public String getStringContent(String uri) throws Exception {
		return new String(getByteContent(uri), "UTF-8");
	}
	public byte[] getByteContent(String uri) throws Exception {
		HttpGet httpRequest = new HttpGet(uri);
		HttpResponse httpResponse = execute(httpRequest);
		return getByteContent(httpResponse);
	}
	public void saveContentAsFile(String uri, File file) throws Exception {
		HttpGet httpRequest = new HttpGet(uri);
		HttpResponse httpResponse = execute(httpRequest);
		HttpEntity entity = httpResponse.getEntity();

		FileOutputStream fileStream = new FileOutputStream(file);
		InputStream contentStream = entity.getContent();
		byte[] bytes = new byte[1024];
		int readBytes = 0;
		while (true) {
			readBytes = contentStream.read(bytes, 0, 1024);
			if (readBytes <= 0)
				break;
			fileStream.write(bytes, 0, readBytes);
		}
		fileStream.close();
		contentStream.close();
		entity.consumeContent();
	}
	public String postStringContent(String uri, String content) throws Exception {
		HttpPost httpPost = new HttpPost(uri);
		httpPost.setHeader(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded");
		
		StringEntity stringEntity = new StringEntity(content, "UTF-8");
		httpPost.setEntity(stringEntity);
		
		HttpResponse httpResponse = execute(httpPost);
		String result = new String(getByteContent(httpResponse), "UTF-8");
		return result;
	}
	public HttpResponse execute(HttpUriRequest httpRequest) throws Exception {
		HttpResponse httpResponse = mWebSession.execute(httpRequest);
		HttpEntity entity = httpResponse.getEntity();
		
		if (entity != null) {
			// 检查内容是否经过gzip压缩
			if (entity.getContentEncoding() != null 
					&& entity.getContentEncoding().getValue().equalsIgnoreCase("gzip")) {
				
				// 创建解压后的实体
				GzipEntityWrapper entityWrapper = new GzipEntityWrapper(entity);
				httpResponse.setEntity(entityWrapper);
				httpResponse.removeHeader(entity.getContentEncoding());
			}
		}

		return httpResponse;
	}
	
	// ### 实现函数 ###
	private byte[] getByteContent(HttpResponse response) throws Exception {
		HttpEntity entity = response.getEntity();
		InputStream contentStream = entity.getContent();

		byte[] bytes = new byte[1024];
		int readBytes = 0;
		ByteArrayBuffer buffer = new ByteArrayBuffer(1024);
		while (true) {
			readBytes = contentStream.read(bytes, 0, 1024);
			if (readBytes <= 0)
				break;
			buffer.append(bytes, 0, readBytes);
		}
		contentStream.close();
		entity.consumeContent();
		return buffer.toByteArray();
	}
}
